#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
    pid_t pid1 = fork();

    if ( pid1 == -1 )
    {
        perror( "fail fork" );
        return -1;
    }
    if ( pid1 > 0)   //父进程执行的代码
    {
        printf( "father: pid %d, spid %d\n", getpid(), pid1 );
        pid_t pid2 = fork();
        if ( pid2 == -1 )
        {
            perror( "fail fork" );
            return -1;
        }
        if ( pid2 > 0 )  // 父进程执行的代码
        {
            printf( "father: pid %d, spid %d\n", getpid(), pid2 );
        }
        else if ( pid2 == 0 )  // 第二次被创建的子进程执行的代码
        {
            printf( "child2: pid %d, ppid %d\n", getpid(), getppid() );
        }
    }
    else if ( pid1 == 0 )   // 第一次被创建的子进程执行的代码
    {
        printf( "child1: pid %d, ppid %d\n", getpid(), getppid() );
    }

    sleep(1);        // 如果不加 sleep , 显示结果可能会不一样

    return 0;
}

/*
函数功能
    一个父进程创建两个子进程.
    子进程打印自己的 PID 和 父进程的 PID
    父进程打印自己的 PID 和 两个子进程的 PID
知识要点:
    只要判断 fork 返回值 >0 , 即为 父进程.
    只要判断 fork 返回值 ==0, 即为 子进程.
    如果不加 sleep , 有可能父进程先结束, 此时 子进程 成为 孤儿进程, 将被系统守护进程收养, 所以 PPID 将成为 系统进程.

    命令 ps -aux | grep a.out
    如果没有加 sleep(1), 可以看到 a.out的状态为 R+, 前台在运行状态的进程
    如果   加 sleep(1), 可以看到 a.out的状态为 S+, 表示这是一个前台休眠状态的进程

    命令 pstree -sp pid
    查看进程树


*/